package config

import (
	"fmt"
	. "go_tempate/common/struct"
	"gopkg.in/yaml.v2"
	"log"
	"os"
	"time"
)

// 返回数据
// ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
var (
	// 环境相关
	ENV string // 当前什么环境

	// api相关
	// ----------------------------------------------------------------------------------------------------------
	ApiPatn string // 路由默认执行路径

	// sql相关
	// ----------------------------------------------------------------------------------------------------------
	SqlType      string // 数据库类型；当前支持mysql
	SqlPath      string // sql操作路径
	MaxOpenConns int    // 数据库最大连接数
	MaxIdleConns int    // 数据库最大空闲连接数
	Timeout      int    // 每个链接的最大生命周期

	// redis相关
	// ----------------------------------------------------------------------------------------------------------
	RedisPath            string        // redis操作路径
	RedisPassword        string        // redis密码
	RedisDB              int           // redis数据库编号
	RefreshEffectiveTime time.Duration // 用户 token单次自动更新最长有效期

	// 日志相关
	// ----------------------------------------------------------------------------------------------------------
	LogFolder  string // 保存日志的文件夹名
	Filename   string // 保存日志路径
	MaxSize    int    // 进行切割之前,日志文件的最大大小(MB为单位)
	MaxAge     int    // 保留旧文件的最大天数
	MaxBackups int    // 保留旧文件的最大个数
	Compress   bool   // 是否压缩
	Stack      bool   // 是否对错误日志堆栈
	Format     string // 日志格式，支持json / console

	// jwt相关
	// ----------------------------------------------------------------------------------------------------------
	JwtCreateTokenKey        []byte        //用户token密匙
	AccessTokenEffectiveTime time.Duration // accessToken 即 用户 token 一次性有效期

	// argon2相关
	// ----------------------------------------------------------------------------------------------------------
	PEKEY    string        // 前端Argon2加密key
	Argon2BG *Argon2Format //后台Argon2加密信息格式
	Argon2PE *Argon2Format //前端Argon2加密信息格式
)

/*
  配置初始化函数

  注意:
    1.根据 config.yml 中的 EnvName 进行配置当前的环境变量名称，获取对应默认配置信息
    2.dev开发环境 test测试环境 prod线上环境；每个环境对应单独的配置yml，例如 dev环境 对应  config/config.dev.yml
    3.防止传入错误环境名称，或并不存在此环境变量，默认在不符合条件中展示 dev的初始化数据
*/
// ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
func init() {
	// 读取 config.yml 文件
	//----------------------------------------------------------------------------------------------------------
	envDate, err := os.ReadFile("config/config.yml")
	if err != nil {
		log.Fatal(err)
	}

	// 解析 config.yml 数据
	//----------------------------------------------------------------------------------------------------------
	var configEnv ConfigENV
	err = yaml.Unmarshal(envDate, &configEnv)
	if err != nil {
		log.Fatal(err)
	}

	//检查当前环境
	//----------------------------------------------------------------------------------------------------------
	ENV = os.Getenv(configEnv.EnvName)

	fmt.Println("当前环境为：", ENV)

	//对应环境config文件名称
	var configName string

	//根据当前环境选择使用对应的公共环境配置信息
	switch os.Getenv(ENV) {
	case "test":
		//测试环境
		configName = "config/config.detection.yml"

	case "prod":
		//线上环境
		configName = "config/config.prod.yml"

	default:
		//如果都不是，则默认到开发环境
		configName = "config/config.dev.yml"
	}

	// 读取 对应环境config 文件
	//----------------------------------------------------------------------------------------------------------
	data, err := os.ReadFile(configName)
	if err != nil {
		log.Fatal(err)
	}

	// 解析 对应环境config 数据
	//----------------------------------------------------------------------------------------------------------
	var config Config // 声明配置文件信息

	//反序列化yaml文件
	err = yaml.Unmarshal(data, &config)

	if err != nil {
		log.Fatal(err)
	}

	//赋值操作
	//----------------------------------------------------------------------------------------------------------
	//api相关
	//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
	ApiPatn = fmt.Sprintf("%s:%s", config.SettingApi.Path, config.SettingApi.Port)

	//sql相关
	//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
	SqlType = config.SettingSql.Type
	SqlPath = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=True&loc=Local", config.SettingSql.User, config.SettingSql.Password, config.SettingSql.Address, config.SettingSql.Port, config.SettingSql.Database, config.SettingSql.Charset)
	MaxOpenConns = config.SettingSql.MaxOpenConns
	MaxIdleConns = config.SettingSql.MaxIdleConns
	Timeout = config.SettingSql.Timeout

	//redis相关
	//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
	RedisPath = fmt.Sprintf("%s:%s", config.SettingRedis.Path, config.SettingRedis.Port)
	RedisPassword = config.SettingRedis.Password
	RedisDB = config.SettingRedis.DB
	RefreshEffectiveTime = time.Second * config.SettingRedis.RefreshTokenKeyTimeout

	//日志相关
	//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
	LogFolder = config.SettingLog.LogFolder
	Filename = LogFolder + "/" + config.SettingLog.Filename
	MaxSize = config.SettingLog.MaxSize
	MaxAge = config.SettingLog.MaxAge
	MaxBackups = config.SettingLog.MaxBackups
	Compress = config.SettingLog.Compress
	Stack = config.SettingLog.Stack
	Format = config.SettingLog.Format

	//jwt相关
	//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
	JwtCreateTokenKey = []byte(config.SettingJwt.AccessTokenKey)
	AccessTokenEffectiveTime = time.Second * config.SettingJwt.AccessTokenTimeout

	//argon2相关
	//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
	PEKEY = config.PEKEY
	Argon2BG = &config.SettingBGArgon2
	Argon2PE = &config.SettingPEArgon2
}
